package edu.tjut.tjutcommunity.recommend.Main;

import edu.tjut.tjutcommunity.entity.User;
import edu.tjut.tjutcommunity.recommend.UserBasedCollaborativeRecommender.MahoutUserBasedCollaborativeRecommender;
import edu.tjut.tjutcommunity.recommend.algorithms.RecommendKit;
import edu.tjut.tjutcommunity.recommend.contentbasedrecommend.ContentBasedRecommender;
import edu.tjut.tjutcommunity.recommend.hotrecommend.HotRecommender;
import org.apache.log4j.Logger;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class JobSetter {

    public static final Logger logger = Logger.getLogger(JobSetter.class);
    /**
     * @param enableCF 是否启用协同过滤(Collaborative Filtering)
     * @param enableCB 是否启用基于内容的推荐(Content-Based Recommendation)
     * @param enableHR 是否启用热点帖子推荐(Hot Post Recommendation)
     */
    boolean enableCF = true, enableCB = true, enableHR = true;

    final
    ContentBasedRecommender contentBasedRecommender;


    public JobSetter(HotRecommender hotRecommender, MahoutUserBasedCollaborativeRecommender mahoutUserBasedCollaborativeRecommender, ContentBasedRecommender contentBasedRecommender) {
        this.hotRecommender = hotRecommender;
        this.mahoutUserBasedCollaborativeRecommender = mahoutUserBasedCollaborativeRecommender;
        this.contentBasedRecommender = contentBasedRecommender;
    }

    public boolean isEnableCF() {
        return enableCF;
    }

    public void setEnableCF(boolean enableCF) {
        this.enableCF = enableCF;
    }

    public boolean isEnableCB() {
        return enableCB;
    }

    public void setEnableCB(boolean enableCB) {
        this.enableCB = enableCB;
    }

    public boolean isEnableHR() {
        return enableHR;
    }

    public void setEnableHR(boolean enableHR) {
        this.enableHR = enableHR;
    }

    final
    HotRecommender hotRecommender;
    final
    MahoutUserBasedCollaborativeRecommender mahoutUserBasedCollaborativeRecommender;


    /**
     * 执行一次推荐
     * 参数forActiveUsers表示是否只针对活跃用户进行新闻推荐，true为是，false为否。
     */
    private void executeInstantJob(List<Integer> userIDList) {

        if (enableCF)
            mahoutUserBasedCollaborativeRecommender.recommend(userIDList);
        if (enableCB)
            contentBasedRecommender.recommend(userIDList);
        if (enableHR)
            hotRecommender.recommend(userIDList);

        System.out.println("本次推荐结束于" + new Date());
    }

    private void executeInstantJobByDerive(User user, Integer derive) {
        ArrayList<Integer> userIDList = new ArrayList<>();
        userIDList.add(user.getUid());
        if (derive == null) {
            mahoutUserBasedCollaborativeRecommender.recommend(userIDList);
            contentBasedRecommender.recommend(userIDList);
            hotRecommender.recommend(userIDList);
        } else if (derive == 0)
            mahoutUserBasedCollaborativeRecommender.recommend(userIDList);
        else if (derive == 1)
            contentBasedRecommender.recommend(userIDList);
        else if (derive == 2)
            hotRecommender.recommend(userIDList);

        System.out.println("为用户" + user.getUsername() + "推荐结束于" + new Date());
    }

    /**
     * 执行一次推荐
     * 参数forActiveUsers表示是否只针对活跃用户进行帖子推荐，true为是，false为否。
     *
     * @param
     */
    public void executeInstantJobForCertainUsers(List<Integer> goalUserList) {
        executeInstantJob(goalUserList);
    }

    /**
     * 为单个用户执行一次推荐
     *
     * @param user
     */
    public void executeInstantJobForSingleUser(User user, Integer derive) {
        executeInstantJobByDerive(user, derive);
    }

    @Async
    public void executeInstantJobForSingleUserAsync(User user, Integer derive) {
        executeInstantJobByDerive(user, derive);
    }

    /**
     * 为所用有用户执行一次新闻推荐
     */
    public void executeInstantJobForAllUsers() {
        executeInstantJob(RecommendKit.getAllUsers());
    }

    /**
     * 为活跃用户进行一次推荐。
     *
     * @param
     */
    public void executeInstantJobForActiveUsers() {
        executeInstantJob(RecommendKit.getActiveUsers());
    }

    /**
     * 生成今天的热点新闻
     */
    public void formTodayTopHotNewsList() {
        hotRecommender.formTodayTopHotNewsList();
    }
}

